iT邦幫忙

2025 iThome 鐵人賽

DAY 29
0
生成式 AI

30 天打造你的 AI Agent:LangChain × n8n 實戰系列 第 29

完整流程 Demo — Gradio + n8n + Gemini

  • 分享至 

  • xImage
  •  

目標與概念

  • 目標:建立前端可上傳 PDF/CSV 或輸入文字問題,後端 n8n 呼叫 Gemini 2.5 Flash 生成摘要或答案,結果回傳至前端。

  • 概念

    • Gradio 提供使用者 UI(文字 + 檔案)
    • n8n Workflow 自動化處理檔案與文字
    • Gemini 2.5 Flash 作為 LLM 生成回覆
  • 注意:請確保 Gemini 2.5 Flash API Key 可用,且 n8n Workflow 已 Activate


Gradio 前端程式(含註解)

import gradio as gr
import requests

# 主函式:接收檔案與問題,呼叫 n8n Webhook
def analyze_file(file, question):
    # 判斷是否有上傳檔案
    if file:
        # 注意:open(file.name, "rb") 必須關閉檔案,或使用 with
        with open(file.name, "rb") as f:
            files = {"file": f}
            data = {"question": question}
            # 呼叫 n8n Webhook,傳送檔案與問題
            response = requests.post(
                "http://localhost:5678/webhook/ai-analyzer",
                data=data,
                files=files
            )
    else:
        # 無檔案時,僅傳送文字內容
        response = requests.post(
            "http://localhost:5678/webhook/ai-analyzer",
            json={"question": question, "content": ""}
        )
    
    # 檢查回應狀態
    if response.status_code == 200:
        # 注意 JSON key 是否與 Function 節點輸出一致
        return response.json().get("result", "Agent 沒回應")
    else:
        return f"Error: {response.text}"

# 建立 Gradio UI
iface = gr.Interface(
    fn=analyze_file,
    inputs=[
        gr.File(label="上傳檔案(PDF / CSV)", file_types=[".pdf", ".csv"]),
        gr.Textbox(label="想詢問的問題", placeholder="例如:幫我摘要報告重點")
    ],
    outputs=gr.Textbox(label="AI 分析結果"),
    title="LLM Agent 智慧文件分析",
    description="上傳文件並輸入問題,AI Agent 自動產生摘要或答案"
)

# 啟動 Gradio
iface.launch()

註解提醒

  • file.name 是檔案路徑,必須用 "rb" 開啟二進位檔
  • 若 n8n Webhook URL 或端口錯誤,會顯示 Error
  • Gradio UI 顯示結果依賴 Function 節點輸出的 JSON key(result

n8n Workflow 範例(含註解)

節點流程

Webhook (/ai-analyzer)
   ↓
Function (解析檔案)
   ↓
Function (轉文字)
   ↓
HTTP Request (呼叫 Gemini 2.5 Flash)
   ↓
Function (整理 LLM 回應)
   ↓
Webhook Response (Last Node)

Function 範例(PDF / CSV 解析)

const { parse } = require('csv-parse/sync');
const pdf = require('pdf-parse');

// 檢查是否有檔案上傳
if (Object.keys($binary).length > 0) {
    if ($binary.data.mimeType === 'application/pdf') {
        // PDF 解析
        return pdf($binary.data).then(data => [{json:{content:data.text}}]);
    } else if ($binary.data.mimeType.includes('csv')) {
        // CSV 解析
        const records = parse($binary.data.toString(), {columns:true});
        return [{json:{content: JSON.stringify(records)}}];
    } else {
        return [{json:{content:"Unsupported file"}}];
    }
} else {
    // 無檔案,使用前端傳入文字
    return [{json:{content:$json["content"]}}];
}

註解提醒

  • PDF 解析需要 pdf-parse 套件
  • CSV 解析需要 csv-parse/sync 套件
  • 注意檔案 MIME type 與 Node 設定一致
  • 若檔案格式不支援,建議回傳錯誤訊息

HTTP Request 範例(呼叫 Gemini 2.5 Flash)

POST https://api.gemini.com/v1/llm
Headers:
  Authorization: Bearer <YOUR_API_KEY>
Body (JSON):
{
  "model": "gemini-2.5-flash",
  "input": "請閱讀以下內容並回答問題: {{$json['question']}}\n內容: {{$json['content']}}",
  "temperature": 0.7,
  "max_tokens": 500
}

註解提醒

  • model 一定要使用 "gemini-2.5-flash"
  • input 可以使用 n8n 表達式 {{$json[...]}}
  • 確認 API Key 有效

Function 範例(整理 LLM 回應)

return [{
  json: {
    result: $json["choices"] ? $json["choices"][0]["text"] : "LLM 沒回應"
  }
}]

註解提醒

  • 確認 choices[0].text 路徑正確
  • 若回傳空值,可加判斷避免 Webhook 回傳空

測試方法

  1. 啟動 n8n Docker → Activate Workflow
  2. 啟動 Gradio App → 瀏覽器開啟
  3. 上傳 PDF/CSV 或僅輸入問題 → Submit
  4. 檢查回傳結果

curl 測試範例

curl -X POST http://localhost:5678/webhook/ai-analyzer \
  -F "file=@sample.pdf" \
  -F "question=幫我摘要重點"

常見錯誤與排查

問題 可能原因 建議處理
LLM 無回應 API Key 錯誤或 Body JSON 不正確 檢查 Key 與輸入格式
PDF / CSV 解析錯誤 套件未安裝或 MIME type 不正確 安裝套件,確認 Node 設定
Webhook 空白 Response Mode 未選 Last Node 調整 Webhook Response Mode
Gradio 顯示空白 Function 節點回傳 JSON key 與前端不一致 確認回傳 key 為 "result"

上一篇
加入檔案上傳功能:PDF、CSV 自動處理
下一篇
LLM Agent 專案技術總結
系列文
30 天打造你的 AI Agent:LangChain × n8n 實戰30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言